wayland: Track orphaned dialogs per display
authorJonas Ådahl <jadahl@gmail.com>
Tue, 26 Apr 2016 03:46:25 +0000 (11:46 +0800)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 26 Apr 2016 12:38:18 +0000 (08:38 -0400)
Don't track all orphaned dialogs globally, as mixing them up with each
other would in most cases trigger errors when we try to pass bogus
values to Wayland requests.

https://bugzilla.gnome.org/show_bug.cgi?id=765474

gdk/wayland/gdkdisplay-wayland.h
gdk/wayland/gdkwindow-wayland.c

index 412c660ba5a432f30d8f23c8836c477c69fe1549..a6cd14f570c959eacd0b1d9f04d6800206b636fe 100644 (file)
@@ -84,6 +84,9 @@ struct _GdkWaylandDisplay
   GHashTable *known_globals;
   GList *on_has_globals_closures;
 
+  /* Keep a list of orphaned dialogs (i.e. without parent) */
+  GList *orphan_dialogs;
+
   struct wl_cursor_theme *scaled_cursor_themes[GDK_WAYLAND_THEME_SCALES_COUNT];
   gchar *cursor_theme_name;
   int cursor_theme_size;
index a646cb3633f1688050b3cbe145a7ec62ccaa246a..eac2e222e9747342b854f457eb9c948a51c4cfef 100644 (file)
@@ -191,14 +191,15 @@ _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
   impl->saved_height = -1;
 }
 
-/* Keep a list of orphaned dialogs (i.e. without parent) */
-static GList *orphan_dialogs;
-
 static void
 _gdk_wayland_screen_add_orphan_dialog (GdkWindow *window)
 {
-  if (!g_list_find (orphan_dialogs, window))
-    orphan_dialogs = g_list_prepend (orphan_dialogs, window);
+  GdkWaylandDisplay *display_wayland =
+    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+
+  if (!g_list_find (display_wayland->orphan_dialogs, window))
+    display_wayland->orphan_dialogs =
+      g_list_prepend (display_wayland->orphan_dialogs, window);
 }
 
 static void
@@ -953,6 +954,9 @@ gdk_wayland_window_sync_parent (GdkWindow *window,
   GdkWindowImplWayland *impl_parent = NULL;
   struct xdg_surface *parent_surface;
 
+  g_assert (parent == NULL ||
+            gdk_window_get_display (window) == gdk_window_get_display (parent));
+
   if (!impl->display_server.xdg_surface)
     return;
 
@@ -978,12 +982,14 @@ gdk_wayland_window_sync_parent (GdkWindow *window,
 static void
 gdk_wayland_window_update_dialogs (GdkWindow *window)
 {
+  GdkWaylandDisplay *display_wayland =
+    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
   GList *l;
 
-  if (!orphan_dialogs)
+  if (!display_wayland->orphan_dialogs)
     return;
 
-  for (l = orphan_dialogs; l; l = l->next)
+  for (l = display_wayland->orphan_dialogs; l; l = l->next)
     {
       GdkWindow *w = l->data;
       GdkWindowImplWayland *impl;
@@ -1830,7 +1836,8 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
       impl->display_server.outputs = NULL;
 
       if (impl->hint == GDK_WINDOW_TYPE_HINT_DIALOG && !impl->transient_for)
-        orphan_dialogs = g_list_remove (orphan_dialogs, window);
+        display_wayland->orphan_dialogs =
+          g_list_remove (display_wayland->orphan_dialogs, window);
     }
 
   _gdk_wayland_window_clear_saved_size (window);
@@ -2291,8 +2298,13 @@ gdk_wayland_window_set_transient_for (GdkWindow *window,
                                       GdkWindow *parent)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkWaylandDisplay *display_wayland =
+    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
   GdkWindow *previous_parent;
 
+  g_assert (parent == NULL ||
+            gdk_window_get_display (window) == gdk_window_get_display (parent));
+
   if (check_transient_for_loop (window, parent))
     {
       g_warning ("Setting %p transient for %p would create a loop", window, parent);
@@ -2310,7 +2322,8 @@ gdk_wayland_window_set_transient_for (GdkWindow *window,
       if (!parent)
         _gdk_wayland_screen_add_orphan_dialog (window);
       else if (!previous_parent)
-        orphan_dialogs = g_list_remove (orphan_dialogs, window);
+        display_wayland->orphan_dialogs =
+          g_list_remove (display_wayland->orphan_dialogs, window);
     }
   gdk_wayland_window_sync_parent (window, NULL);
   if (should_map_as_subsurface (window) &&